package com.authine.cloudpivot.ext.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.app.permission.impl.utils.PermissionHelper;
import com.authine.cloudpivot.engine.api.exceptions.ServiceException;
import com.authine.cloudpivot.engine.api.model.BaseModel;
import com.authine.cloudpivot.engine.api.model.PageableSupport;
import com.authine.cloudpivot.engine.api.model.application.AppFunctionModel;
import com.authine.cloudpivot.engine.api.model.bizmodel.BizPropertyModel;
import com.authine.cloudpivot.engine.api.model.organization.DepartmentModel;
import com.authine.cloudpivot.engine.api.model.organization.RoleUserModel;
import com.authine.cloudpivot.engine.api.model.permission.*;
import com.authine.cloudpivot.engine.api.model.runtime.CirculateItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.system.AdminModel;
import com.authine.cloudpivot.engine.api.spec.WorkItemQuerySpec;
import com.authine.cloudpivot.engine.component.query.api.FilterExpression;
import com.authine.cloudpivot.engine.component.query.api.helper.Q;
import com.authine.cloudpivot.engine.enums.ErrCode;
import com.authine.cloudpivot.engine.enums.type.*;
import com.authine.cloudpivot.web.api.service.EngineService;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Aspect
@Component
public class AppDataAuthAspect {

    @Autowired
    private EngineService engineService;

    @Value("${cloudpivot.permission.deptScope.useNewLogic:false}")
    private Boolean useNewLogic;

    private void buildApproveHandleFilter(List<FilterExpression> filterExpressionList, String userId) {
        // 查询客户名下所有已办
        WorkItemQuerySpec workItemQuerySpec = new WorkItemQuerySpec();
        workItemQuerySpec.setUserId(userId);
//        workItemQuerySpec.setAppCode();
//        workItemQuerySpec.setWorkflowCode();
        Sort sort = Sort.by(Sort.DEFAULT_DIRECTION, DefaultPropertyType.CREATED_TIME.getCode());
        PageableSupport pageableSupport = new PageableSupport(0, 500, sort);
        Page<WorkItemModel> workItemModels = engineService.getWorkflowInstanceFacade().queryFinishedWorkItems(workItemQuerySpec, pageableSupport);
        FilterExpression expression = null;
        Set<String> flowIds = new HashSet<>();
        flowIds.add("");
        if (CollectionUtils.isNotEmpty(workItemModels.getContent())) {
            flowIds = workItemModels.getContent().stream().map(x -> x.getInstanceId()).collect(Collectors.toSet());
        }
        expression = Q.it("workflowInstanceId", FilterExpression.Op.In, flowIds);
        filterExpressionList.add(expression);
    }

    private void buildHandleUserFilter(List<FilterExpression> filterExpressionList,
                                       String userId){
        HashSet<String> flowIds = new HashSet<>();
        // 查询用户名下所有待阅
        WorkItemQuerySpec workItemQuerySpec = new WorkItemQuerySpec();
        workItemQuerySpec.setUserId(userId);

        Sort sort = Sort.by(Sort.Direction.DESC, DefaultPropertyType.CREATED_TIME.getCode());
        PageableSupport pageableSupport = new PageableSupport(0,Integer.MAX_VALUE,sort);

        Page<WorkItemModel> workItemModels = engineService.getWorkflowInstanceFacade().queryWorkItems(workItemQuerySpec, pageableSupport);
        if (CollectionUtils.isNotEmpty(workItemModels.getContent())) {
            Set<String> collect = workItemModels.getContent().stream().map(x -> x.getInstanceId()).collect(Collectors.toSet());
            flowIds.addAll(collect);
        }

        // 查询用户名下所有待阅
        Page<CirculateItemModel> circulateItemModels = engineService.getWorkflowInstanceFacade().queryCirculateItems(workItemQuerySpec, pageableSupport);
        if (CollectionUtils.isNotEmpty(circulateItemModels.getContent())) {
            Set<String> collect = circulateItemModels.getContent().stream().map(x -> x.getInstanceId()).collect(Collectors.toSet());
            flowIds.addAll(collect);
        }

        FilterExpression expression = null;
        if (CollectionUtils.isNotEmpty(flowIds)) {
            expression = Q.or(Q.it("workflowInstanceId", FilterExpression.Op.In, flowIds),
                    Q.it(DefaultPropertyType.CREATER.getCode(), FilterExpression.Op.Eq,userId));
        } else {
            expression = Q.it(DefaultPropertyType.CREATER.getCode(), FilterExpression.Op.Eq,userId);
        }
        filterExpressionList.add(expression);
    }

    
    @Around(value = "execution(* com.authine.cloudpivot.engine.service.impl.spi.DataPermissionRuntimeServiceImpl.getQueryFilterExpression(..))")
    public Object filter(ProceedingJoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        String userId = args[0].toString();
        String schemaCode = args[1].toString();
        boolean isOwner = (boolean) args[2];
        AppFunctionModel appFunction = engineService.getApplicationFacade().getAppFunctionByCode(schemaCode);
        if (appFunction == null) {
            throw new ServiceException(ErrCode.APP_FUNCTION_MODEL_NOTEXIST);
        } else {
            AppPackagePermissionModel appPackagePermissionModel = engineService.getPermissionManagementFacade().getAppPackagePermission(appFunction.getAppCode());
            if (appPackagePermissionModel == null) {
                return FilterExpression.empty;
            } else if (!Boolean.TRUE.equals(appPackagePermissionModel.getAppPackage().getEnabled())) {
                throw new ServiceException(ErrCode.APP_FORBIDDENED);
            } else {
                Boolean isAdminOrSysManager = isAdmin(userId) || isSysManager(userId);
                if (Boolean.TRUE.equals(isAdminOrSysManager)) {
                    // 管理员不做权限过滤
                    return FilterExpression.empty;

                } else {
                    String appCode = appFunction.getAppCode();
                    boolean isAllVisiable = appPackagePermissionModel.getVisibleType() == VisibleType.ALL_VISIABLE;
                    List<PermissionGroupModel> permissionGroupModels = engineService.getPermissionManagementFacade().getPermissionGroupsByAppCodeAndUserId(appCode, userId);
                    log.info("permissionGroupModels:{}", permissionGroupModels);
                    List<AppFunctionPermissionModel> appFunctionPermissionModels = getCommonDataPermission(schemaCode, isAllVisiable, isOwner, permissionGroupModels);

                    AdminModel subAdminModel = engineService.getPermissionManagementFacade().getAdminByAdminTypeAndUserId(AdminType.APP_MNG, userId);
                    boolean isSubAdmin = isSubAdminForApp(subAdminModel, appCode);
                    List<FilterExpression> filterExpressions = Lists.newArrayList();
                    boolean checkAppAndBizSchemaPerm = checkAppAndBizSchemaPerm(isAllVisiable, userId, schemaCode, permissionGroupModels);
                    if (!isSubAdmin && !checkAppAndBizSchemaPerm) {
                        throw new ServiceException(40002L, "当前列表数据没有查看权限");
                    } else {
                        if (CollectionUtils.isNotEmpty(appFunctionPermissionModels)) {
                            appFunctionPermissionModels = appFunctionPermissionModels.stream().filter(AppFunctionPermissionModel::getVisible).collect(Collectors.toList());
                        }
                        if (isOwner && CollectionUtils.isNotEmpty(appFunctionPermissionModels) && !isSubAdmin) {
                            appFunctionPermissionModels = appFunctionPermissionModels.stream().filter(AppFunctionPermissionModel::getEditOwnerAble).collect(Collectors.toList());
                        }

                        if (!isSubAdmin && CollectionUtils.isEmpty(appFunctionPermissionModels)) {
                            throw new ServiceException(ErrCode.NO_SCHEMA_DATA_AUTHROITY.getErrCode(), ErrCode.NO_SCHEMA_DATA_AUTHROITY.getErrMsg());
                        } else {
                            if (CollectionUtils.isEmpty(appFunctionPermissionModels) && isSubAdmin) {
                                filterExpressions.add(Q.it(DefaultPropertyType.OWNER.getCode(), FilterExpression.Op.Eq, userId));
                            }

                            List departments;
                            if (CollectionUtils.isNotEmpty(appFunctionPermissionModels)) {
                                // 所有数据
                                departments = appFunctionPermissionModels.stream().filter((model) -> {
                                    return model.getDataPermissionType() == DataPermissionType.ALL;
                                }).collect(Collectors.toList());

                                // 管理范围数据
                                List<AppFunctionPermissionModel> roleManageScopePerms = appFunctionPermissionModels.stream().filter((model) -> {
                                    return model.getDataPermissionType() == DataPermissionType.ROLE_MANAGE_SCOPE;
                                }).collect(Collectors.toList());

                                // 如果选择了所有数据不做权限控制
                                if (CollectionUtils.isNotEmpty(departments)) {
                                    return FilterExpression.empty;
                                }

                                // 角色管理范围权限构建
                                buildRoleManageScopeFilter(roleManageScopePerms, permissionGroupModels, userId, filterExpressions);
                            }


                            if (isSubAdmin) {
                                departments = getSubAdminDeptScope(subAdminModel, appCode);
                                filterExpressions = PermissionHelper.bulidSubAdminDeptScopeFilter(departments);
                                boolean externaLinkVisiable = checkExternalLinkVisiable(subAdminModel, appCode);
                                if (externaLinkVisiable) {
                                    filterExpressions.add(Q.it(DefaultPropertyType.OWNER.getCode(), FilterExpression.Op.Eq, "2ccf3b346706a6d3016706dc51c0022b"));
                                }
                            }

                            // 普通用户权限过滤
                            getNormalUserFilter(filterExpressions, appFunctionPermissionModels, userId);
                            return tileFilterExpressions(filterExpressions);
                        }
                    }
                }
            }
        }
    }
    
    private Boolean isAdmin(String userid) {
        AdminModel adminModel = engineService.getPermissionManagementFacade().getAdminByAdminTypeAndUserId(AdminType.ADMIN, userid);
        return !Objects.isNull(adminModel);
    }

    private Boolean isSysManager(String userid) {
        AdminModel adminModel = engineService.getPermissionManagementFacade().getAdminByAdminTypeAndUserId(AdminType.SYS_MNG, userid);
        return !Objects.isNull(adminModel);
    }

    private List<AppFunctionPermissionModel> getCommonDataPermission(String schemaCode, boolean isAllVisiable, boolean isOwner, List<PermissionGroupModel> permissionGroupModels) {
        if (isAllVisiable) {
            AppFunctionPermissionModel appFunctionPermissionModel = new AppFunctionPermissionModel();
            appFunctionPermissionModel.setEditable(true);
            appFunctionPermissionModel.setSchemaCode(schemaCode);
            appFunctionPermissionModel.setVisible(true);
            appFunctionPermissionModel.setCreatable(true);
            appFunctionPermissionModel.setDataPermissionType(DataPermissionType.ONLY_MYSELF);
            appFunctionPermissionModel.setDeletable(true);
            appFunctionPermissionModel.setExportable(true);
            appFunctionPermissionModel.setImportable(true);
            List<AppFunctionPermissionModel> appFunctionPermissionModelList = new ArrayList(1);
            appFunctionPermissionModelList.add(appFunctionPermissionModel);
            return appFunctionPermissionModelList;
        } else {
            List<AppFunctionPermissionModel> appFunctionPermissionModels = PermissionHelper.getCommonDataPermission(schemaCode, permissionGroupModels, isOwner);
            if (CollectionUtils.isEmpty(appFunctionPermissionModels)) {
                AppFunctionPermissionModel appFunctionPermissionModel = new AppFunctionPermissionModel();
                appFunctionPermissionModel.setEditable(true);
                appFunctionPermissionModel.setSchemaCode(schemaCode);
                appFunctionPermissionModel.setVisible(true);
                appFunctionPermissionModel.setCreatable(true);
                appFunctionPermissionModel.setDataPermissionType(DataPermissionType.ONLY_MYSELF);
                appFunctionPermissionModel.setDeletable(true);
                appFunctionPermissionModel.setExportable(true);
                appFunctionPermissionModel.setImportable(true);
                List<AppFunctionPermissionModel> appFunctionPermissionModelList = new ArrayList();
                appFunctionPermissionModelList.add(appFunctionPermissionModel);
                return appFunctionPermissionModelList;
            } else {
                Iterator var6 = appFunctionPermissionModels.iterator();

                while(var6.hasNext()) {
                    AppFunctionPermissionModel appFunctionPermissionModel = (AppFunctionPermissionModel)var6.next();
                    if (appFunctionPermissionModel.getDataPermissionType() == DataPermissionType.CUSTOM) {
                        appFunctionPermissionModel.setConditions(engineService.getPermissionManagementFacade().getAppFunctionPermissionConditionsByFunctionId(appFunctionPermissionModel.getId()));
                    }
                }

                return appFunctionPermissionModels;
            }
        }
    }

    private boolean isSubAdminForApp(AdminModel subAdminModel, String appCode) {
        if (Objects.isNull(subAdminModel)) {
            return false;
        } else {
            List<AdminPermissionGroupModel> adminGroups = subAdminModel.getAdminGroups();
            List<String> appPackages = adminGroups.stream().map(AdminPermissionGroupModel::getAppPackages).collect(Collectors.toList());
            return !CollectionUtils.isEmpty(appPackages) && !StringUtils.isBlank(appCode) ? appPackages.stream().anyMatch((it) -> {
                return StringUtils.equals(appCode, it);
            }) : false;
        }
    }

    private boolean checkAppAndBizSchemaPerm(boolean isAllVisiable, String userId, String schemaCode, List<PermissionGroupModel> permissionGroupModels) {
        if (isAllVisiable) {
            return true;
        } else if (CollectionUtils.isEmpty(permissionGroupModels)) {
            return false;
        } else {
            Iterator var5 = permissionGroupModels.iterator();

            List appFunctionPermissionTemplates;
            do {
                if (!var5.hasNext()) {
                    return false;
                }

                PermissionGroupModel permissionGroup = (PermissionGroupModel)var5.next();
                List<AppFunctionPermissionModel> appFunctionPermissionModels = permissionGroup.getDataPermissionGroups();
                if (CollectionUtils.isEmpty(appFunctionPermissionModels)) {
                    log.debug("权限没有配置");
                    return true;
                }

                List<AppFunctionPermissionModel> appFunctionPermissionModelList = (List)appFunctionPermissionModels.stream().filter((t) -> {
                    return t.getSchemaCode().equals(schemaCode);
                }).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(appFunctionPermissionModelList)) {
                    log.debug("权限默认配置");
                    return true;
                }

                appFunctionPermissionTemplates = (List)appFunctionPermissionModels.stream().filter((t) -> {
                    return t.getSchemaCode().equals(schemaCode) && t.getVisible();
                }).collect(Collectors.toList());
            } while(!CollectionUtils.isNotEmpty(appFunctionPermissionTemplates));

            return true;
        }
    }

    private void buildRoleManageScopeFilter(List<AppFunctionPermissionModel> roleManageScopePerms, List<PermissionGroupModel> permissionGroupModels, String userId, List<FilterExpression> filterExpressions) {
        if (!CollectionUtils.isEmpty(roleManageScopePerms)) {
            List<RoleUserModel> roleUserModelList = engineService.getOrganizationFacade().getRoleUsersByUserId(userId);
            if (!CollectionUtils.isEmpty(roleUserModelList)) {
                Set<String> roleIdSet = Sets.newHashSet();
                List<String> permissionGroupIdList = roleManageScopePerms.stream().map(AppFunctionPermissionModel::getPermissionGroupId).collect(Collectors.toList());
                permissionGroupModels.stream().filter((group) -> {
                    return !StringUtils.isBlank(group.getRoles()) && permissionGroupIdList.contains(group.getId());
                }).forEach((group) -> {
                    JSONArray jsonArray = JSON.parseArray(group.getRoles());
                    Iterator var3 = jsonArray.iterator();

                    while(var3.hasNext()) {
                        Object object = var3.next();
                        JSONObject jsonObject = (JSONObject)object;
                        roleIdSet.add(jsonObject.getString("id"));
                    }

                });
                Set<String> deptScopeSet = Sets.newHashSet();
                Set<String> userScopeSet = Sets.newHashSet();
                Iterator var10 = roleUserModelList.iterator();

                while(var10.hasNext()) {
                    RoleUserModel roleUserModel = (RoleUserModel)var10.next();
                    if (roleIdSet.contains(roleUserModel.getRoleId())) {
                        String scope = roleUserModel.getOuScope();
                        if (!StringUtils.isBlank(scope)) {
                            try {
                                deptScopeSet.addAll(JSON.parseArray(scope, String.class));
                            } catch (Exception var15) {
                                log.error("解析角色范围异常.", var15);
                            }
                        }

                        String usscope = roleUserModel.getUsScope();
                        if (StringUtils.isNotBlank(usscope)) {
                            try {
                                userScopeSet.addAll(JSON.parseArray(usscope, String.class));
                            } catch (Exception var16) {
                                log.error("解析角色范围(用户)异常.", var16);
                            }
                        }
                    }
                }

                List<FilterExpression> filterExpressionList = Lists.newArrayList();
                if (CollectionUtils.isNotEmpty(userScopeSet)) {
                    filterExpressionList.add(Q.it(DefaultPropertyType.OWNER.getCode(), FilterExpression.Op.In, Lists.newArrayList(userScopeSet)));
                }

                if (CollectionUtils.isNotEmpty(deptScopeSet)) {
                    if (Boolean.TRUE.equals(useNewLogic)) {
                        engineService.getOrganizationFacade().getDepartmentsByDeptIds(Lists.newArrayList(deptScopeSet)).stream().filter((it) -> {
                            return !Boolean.TRUE.equals(it.getDeleted()) && StringUtils.isNotBlank(it.getQueryCode());
                        }).forEach((dept) -> {
                            String field = DefaultPropertyType.OWNER_DEPT_QUERY_CODE.getCode();
                            filterExpressionList.add(Q.it(field, FilterExpression.Op.Eq, dept.getQueryCode()));
                            filterExpressionList.add(Q.it(field, FilterExpression.Op.LLike, dept.getQueryCode() + "#"));
                        });
                    } else {
                        List<DepartmentModel> departmentModels = engineService.getOrganizationFacade().getDepartmentsChildList(Lists.newArrayList(deptScopeSet), true);
                        if (CollectionUtils.isNotEmpty(departmentModels)) {
                            filterExpressionList.add(Q.it(DefaultPropertyType.OWNER_DEPT_ID.getCode(), FilterExpression.Op.In, departmentModels.stream().map(BaseModel::getId).collect(Collectors.toList())));
                        }
                    }
                }

                if (filterExpressionList.size() == 1) {
                    filterExpressions.add(filterExpressionList.get(0));
                } else if (filterExpressionList.size() > 1) {
                    filterExpressions.add(Q.or(filterExpressionList));
                } else {
                    filterExpressions.add(Q.it(DefaultPropertyType.OWNER_DEPT_ID.getCode(), FilterExpression.Op.Eq, "1"));
                }

            }
        }
    }

    private List<DepartmentScopeModel> getSubAdminDeptScope(AdminModel subAdminModel, String appCode) {
        if (Objects.isNull(subAdminModel)) {
            return Collections.emptyList();
        } else {
            List<AdminPermissionGroupModel> adminGroups = subAdminModel.getAdminGroups();
            AdminPermissionGroupModel adminGroup = (AdminPermissionGroupModel)adminGroups.stream().filter((it) -> {
                return StringUtils.equals(it.getAppPackages(), appCode);
            }).findFirst().orElse(null);
            return adminGroup == null ? Collections.emptyList() : adminGroup.getDepartments();
        }
    }

    private boolean checkExternalLinkVisiable(AdminModel subAdminModel, String appCode) {
        if (subAdminModel == null) {
            return false;
        } else {
            List<AdminPermissionGroupModel> adminGroups = subAdminModel.getAdminGroups();
            AdminPermissionGroupModel adminGroup = (AdminPermissionGroupModel)adminGroups.stream().filter((it) -> {
                return StringUtils.equals(it.getAppPackages(), appCode);
            }).findFirst().orElse(null);
            if (adminGroup == null) {
                return false;
            } else {
                return !Boolean.FALSE.equals(adminGroup.getExternalLinkVisible());
            }
        }
    }



    private void getNormalUserFilter(List<FilterExpression> filterExpressionList, List<AppFunctionPermissionModel> appFunctionPermissionModels, String userId) {
        if (!CollectionUtils.isEmpty(appFunctionPermissionModels)) {
            FilterExpression filterExpression = FilterExpression.empty;
            boolean filterDept = false;
            boolean filterMySelf = false;
            boolean filterCustom = false;
            boolean filterCurrentHandler = false;
            boolean filterApproved = false;

            Iterator var8 = appFunctionPermissionModels.iterator();
            // 遍历权限配置
            while(var8.hasNext()) {
                AppFunctionPermissionModel appFunctionPermissionModel = (AppFunctionPermissionModel)var8.next();
                if (appFunctionPermissionModel.getDataPermissionType() == DataPermissionType.MY_DEPARTMENT) {
                    filterDept = true;
                }

                if (appFunctionPermissionModel.getDataPermissionType() == DataPermissionType.ONLY_MYSELF) {
                    filterMySelf = true;
                }

                if (appFunctionPermissionModel.getDataPermissionType() == DataPermissionType.CUSTOM) {
                    filterCustom = true;
                }
                // 当前处理人可见
                if (appFunctionPermissionModel.getDataPermissionType() == DataPermissionType.CURRNET_HANDLER) {
                    filterCurrentHandler = true;
                }
                // 历史处理人
                if (appFunctionPermissionModel.getDataPermissionType() == DataPermissionType.APPROVED_HANDLER) {
                    filterApproved = true;
                }
            }

            if (filterDept) {

                List<DepartmentModel> departments = engineService.getOrganizationFacade().getDepartmentsByUserId(userId);
                filterExpressionList.addAll(PermissionHelper.buildDeptFilter(departments));
            }

            if (filterMySelf && !"2ccf3b346706a6d3016706dc51c0022b".equals(userId)) {
                filterExpression = Q.it(DefaultPropertyType.OWNER.getCode(), FilterExpression.Op.Eq, userId);
            }

            if (filterCustom) {
                disposeCustomFilter(filterExpressionList, appFunctionPermissionModels, userId);
            }

            // 扩展处理人可见类型
            if (filterCurrentHandler) {
                buildHandleUserFilter(filterExpressionList, userId);
            }

            // 历史处理人
            if (filterApproved) {
                buildApproveHandleFilter(filterExpressionList, userId);
            }

            if (filterExpression != FilterExpression.empty) {
                filterExpressionList.add(filterExpression);
            }

        }
    }


    protected void disposeCustomFilter(List<FilterExpression> filterExpressionList, List<AppFunctionPermissionModel> appFunctionPermissionModels, String userId) {
        if (!CollectionUtils.isEmpty(appFunctionPermissionModels)) {
            List<AppFunctionPermissionModel> appFunctionPermissions = appFunctionPermissionModels.stream().filter((t) -> {
                return t.getDataPermissionType() == DataPermissionType.CUSTOM;
            }).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(appFunctionPermissions)) {
                disposeCustomPermSelection(appFunctionPermissions, userId);
                String schemaCode = (appFunctionPermissions.get(0)).getSchemaCode();
                List<BizPropertyModel> properties = engineService.getModelManagementFacade().getBizSchemaBySchemaCode(schemaCode).getProperties();
                Iterator var7 = appFunctionPermissions.iterator();

                while(true) {
                    while(var7.hasNext()) {
                        AppFunctionPermissionModel appFunctionPermission = (AppFunctionPermissionModel)var7.next();
                        List<AppFunctionPermissionConditionModel> appFunctionPermissionConditions = appFunctionPermission.getConditions();
                        if (CollectionUtils.isEmpty(appFunctionPermissionConditions)) {
                            filterExpressionList.add(Q.it(DefaultPropertyType.OWNER.getCode(), FilterExpression.Op.Eq, userId));
                        } else {
                            List<FilterExpression> templateFilterExpressions = Lists.newArrayList();
                            Iterator var11 = appFunctionPermissionConditions.iterator();

                            while(true) {
                                while(var11.hasNext()) {
                                    AppFunctionPermissionConditionModel appFunctionPermissionCondition = (AppFunctionPermissionConditionModel)var11.next();
                                    FilterExpression.Op op = PermissionHelper.disposeOperator(appFunctionPermissionCondition);
                                    FilterExpression.Item it = parseFilterExpression(appFunctionPermissionCondition, properties);
                                    FilterExpression item = FilterExpression.empty;
                                    if (StringUtils.isNotEmpty(appFunctionPermissionCondition.getValue()) && (op == FilterExpression.Op.NotEq || op == FilterExpression.Op.NotLike)) {
                                        item = Q.it(appFunctionPermissionCondition.getPropertyCode(), FilterExpression.Op.Eq, null);
                                    }

                                    if ((item).isEmpty() && Objects.isNull(it.value)) {
                                        if (appFunctionPermissionCondition.getOperatorType() == OperatorType.IS_NOT_NULL) {
                                            templateFilterExpressions.add(Q.and(it, Q.it(it.field, it.op, ""), new FilterExpression[0]));
                                        } else {
                                            templateFilterExpressions.add(Q.or(it, Q.it(it.field, it.op, ""), new FilterExpression[0]));
                                        }
                                    } else {
                                        String[] split = StringUtils.split(it.value.toString(), "##_&&");
                                        PermissionHelper.buildMultiValueFilter(item, split, it, appFunctionPermissionCondition, templateFilterExpressions);
                                    }
                                }

                                if (!CollectionUtils.isEmpty(templateFilterExpressions)) {
                                    if (appFunctionPermission.getFilterType() == FilterType.ALL) {
                                        if (templateFilterExpressions.size() > 1) {
                                            filterExpressionList.add(Q.and(templateFilterExpressions));
                                        }
                                    } else if (templateFilterExpressions.size() > 1) {
                                        filterExpressionList.add(Q.or(templateFilterExpressions));
                                    }

                                    if (templateFilterExpressions.size() == 1) {
                                        filterExpressionList.add(templateFilterExpressions.get(0));
                                    }
                                }
                                break;
                            }
                        }
                    }
                    return;
                }
            }
        }
    }


    private void disposeCustomPermSelection(List<AppFunctionPermissionModel> appFunctionPermissions, String userId) {
        Iterator var3 = appFunctionPermissions.iterator();

        while(var3.hasNext()) {
            AppFunctionPermissionModel appFunctionPermission = (AppFunctionPermissionModel)var3.next();
            appFunctionPermission.getConditions().forEach((t) -> {
                String deptIdCollect;
                if (Objects.equals(t.getValue(), "SELF_D")) {
                    if (t.getOperatorType() != OperatorType.CONTAINS && t.getOperatorType() != OperatorType.NOT_CONTAINS) {
                        deptIdCollect = getUserDeptIds(userId);
                        String[] split = deptIdCollect.split("##_&&");
                        if (split.length > 1) {
                            StringBuilder sb = new StringBuilder();
                            String[] var6 = split;
                            int var7 = split.length;

                            for(int var8 = 0; var8 < var7; ++var8) {
                                String deptId = var6[var8];
                                String idTemp = "[{\"id\":\"" + deptId + "\",\"type\":1}]";
                                sb.append(idTemp).append("##_&&");
                            }

                            t.setValue(sb.toString());
                        } else {
                            t.setValue("[{\"id\":\"" + split[0] + "\",\"type\":1}]");
                        }
                    } else {
                        deptIdCollect = getUserParentDeptIds(userId);
                        t.setValue(deptIdCollect);
                    }
                }

                if (Objects.equals(t.getValue(), "SELF_P")) {
                    if (t.getOperatorType() != OperatorType.CONTAINS && t.getOperatorType() != OperatorType.NOT_CONTAINS) {
                        t.setValue("[{\"id\":\"" + userId + "\",\"type\":3}]");
                    } else {
                        deptIdCollect = getUserParentDeptIds(userId);
                        t.setValue(userId + "##_&&" + deptIdCollect);
                    }
                }

            });
        }

    }

    private FilterExpression.Item parseFilterExpression(AppFunctionPermissionConditionModel appFunctionPermissionCondition, List<BizPropertyModel> properties) {
        FilterExpression.Op op = PermissionHelper.disposeOperator(appFunctionPermissionCondition);
        BizPropertyModel bizPropertyModel = properties.stream().filter((t) -> {
            return t.getCode().equals(appFunctionPermissionCondition.getPropertyCode());
        }).collect(Collectors.toList()).get(0);
        String field = appFunctionPermissionCondition.getPropertyCode();
        if (DefaultPropertyType.CREATER.getCode().equals(appFunctionPermissionCondition.getPropertyCode()) && (OperatorType.OF == appFunctionPermissionCondition.getOperatorType() || OperatorType.NOT_OF == appFunctionPermissionCondition.getOperatorType())) {
            field = DefaultPropertyType.CREATED_DEPT_ID.getCode();
        }

        if (DefaultPropertyType.OWNER.getCode().equals(appFunctionPermissionCondition.getPropertyCode()) && (OperatorType.OF == appFunctionPermissionCondition.getOperatorType() || OperatorType.NOT_OF == appFunctionPermissionCondition.getOperatorType())) {
            field = DefaultPropertyType.OWNER_DEPT_ID.getCode();
        }

        return bizPropertyModel.getPropertyType() == BizPropertyType.DATE && OperatorType.IS_NOT_NULL == appFunctionPermissionCondition.getOperatorType() ? Q.it(bizPropertyModel.getCode(), FilterExpression.Op.NotEq, "") : Q.it(field, op, parseValue(appFunctionPermissionCondition, bizPropertyModel));
    }


    private Object parseValue(AppFunctionPermissionConditionModel appFunctionPermissionCondition, BizPropertyModel bizPropertyModel) {
        if (!StringUtils.isNotEmpty(appFunctionPermissionCondition.getValue()) || appFunctionPermissionCondition.getOperatorType() != OperatorType.OF && appFunctionPermissionCondition.getOperatorType() != OperatorType.NOT_OF || !appFunctionPermissionCondition.getPropertyCode().equals(DefaultPropertyType.CREATER.getCode()) && !appFunctionPermissionCondition.getPropertyCode().equals(DefaultPropertyType.OWNER.getCode())) {
            if (StringUtils.isEmpty(appFunctionPermissionCondition.getValue())) {
                if (bizPropertyModel.getPropertyType() == BizPropertyType.SHORT_TEXT && OperatorType.IS_NOT_NULL != appFunctionPermissionCondition.getOperatorType() && OperatorType.IS_NULL != appFunctionPermissionCondition.getOperatorType()) {
                    return "";
                } else {
                    return bizPropertyModel.getPropertyType() == BizPropertyType.NUMERICAL && OperatorType.IS_NOT_NULL != appFunctionPermissionCondition.getOperatorType() && OperatorType.IS_NULL != appFunctionPermissionCondition.getOperatorType() ? 0 : null;
                }
            } else {
                return appFunctionPermissionCondition.getValue();
            }
        } else {
            List<String> deptIds = Lists.newArrayList();

            try {
                String value = appFunctionPermissionCondition.getValue();
                if (StringUtils.isNotEmpty(value) && !"\"\"".equals(value)) {
                    log.debug("部门: {}", value);
                    JSONArray depts = JSON.parseArray(value);
                    Iterator var6 = depts.iterator();

                    while(var6.hasNext()) {
                        Object dept = var6.next();
                        deptIds.add(((JSONObject)dept).getString(DefaultPropertyType.ID.getCode()));
                    }

                    List<DepartmentModel> departmentModels = engineService.getOrganizationFacade().getDepartmentsChildList(deptIds, true);
                    deptIds = departmentModels.stream().map(BaseModel::getId).collect(Collectors.toList());
                }
            } catch (JSONException var8) {
                log.error("解析部门异常值:{}", appFunctionPermissionCondition.getValue());
            }

            return deptIds;
        }
    }

    private FilterExpression tileFilterExpressions(List<FilterExpression> filterExpressions) {
        if (CollectionUtils.isEmpty(filterExpressions)) {
            return FilterExpression.empty;
        } else if (CollectionUtils.size(filterExpressions) > 1) {
            return Q.or(filterExpressions);
        } else {
            return CollectionUtils.size(filterExpressions) == 1 ? filterExpressions.get(0) : FilterExpression.empty;
        }
    }

    private String getUserDeptIds(String userId) {
        
        List<DepartmentModel> departmentModels = engineService.getOrganizationFacade().getDepartmentsByUserId(userId);
        return departmentModels.stream().map(BaseModel::getId).collect(Collectors.joining("##_&&"));
    }

    private String getUserParentDeptIds(String userId) {
        Map<String, List<DepartmentModel>> userParentDeptMap = engineService.getOrganizationFacade().getParentDepartmentsByUserIds(Lists.newArrayList(new String[]{userId}));
        List<DepartmentModel> parentDeptList = userParentDeptMap.get(userId);
        return CollectionUtils.isEmpty(parentDeptList) ? "" : parentDeptList.stream().map(BaseModel::getId).collect(Collectors.joining("##_&&"));
    }
}
